/**   
 * @Title: BaseDaoImpl.java 
 * CopyRight(c)2010-DMX 
 */
package com.dmx.fw.dao.hibernateimpl;
 
import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.metadata.ClassMetadata;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.dmx.fw.bean.PageInfo;
import com.dmx.fw.dao.interfaces.Dao;

/** 
 * @Description: use hibernate implements Dao 
 * @author: system
 * @date: 2006
 * @version V1.0 
 * 
 */
public class BaseDaoImpl extends HibernateDaoSupport implements Dao {
	protected final static Logger log = Logger.getLogger(BaseDaoImpl.class);	

    /**
     * @see com.dmx.fw.dao.interfaces.Dao#saveObject(java.lang.Object)
     */
    public void saveObject(Object o) throws Exception{
        getHibernateTemplate().saveOrUpdate(o);
    }
    
    /**
     * @see com.dmx.fw.dao.interfaces.Dao#updateObject(java.lang.Object)
     */
    public void updateObject(final Object o){
    	getHibernateTemplate().update(o);
    }
    
    /**
     * @see com.dmx.fw.dao.interfaces.Dao#create(java.lang.Object)
     */
    public Long create(Object o) {
    	try {    		
    		return (Long) getHibernateTemplate().save(o);
		} catch (Exception e) {
			e.printStackTrace();
			return null;// TODO: handle exception
		}    
    }
    
    /**
     * @see com.dmx.fw.dao.interfaces.Dao#flush()
     */
    public void flush(){
    	getHibernateTemplate().flush();
    }

    /**
     * @see  com.dmx.fw.dao.interfaces.Dao#getObject(java.lang.Class, java.io.Serializable)
     */
    public Object getObject(Class clazz, Serializable id) {
        Object o = getHibernateTemplate().get(clazz, id);
        
        //dont throw Exception
        //if (o == null) {
        //    throw new ObjectRetrievalFailureException(clazz, id);
        //}

        return o;
    }

    /**
     * @see com.dmx.fw.dao.interfaces.Dao#getObjects(java.lang.Class)
     */
    public List getObjects(Class clazz) {
        return getHibernateTemplate().loadAll(clazz);
    }
    public List getObjects(Class clazz,Serializable[] id){
    	if(id==null || id.length==0) 
    		return new ArrayList(0);
    	
    	StringBuffer buffer=new StringBuffer(100);
    	buffer.append("select a from ").append(clazz.getName()).append(" a where a.")
    	.append(getIdentifierName(this.getSessionFactory(),clazz)).append(" in(");
    	for(int i=0;i<id.length;i++){
			if(i>0)
			   buffer.append(",");
			buffer.append(id[i]);
		}
    	buffer.append(") ");
    	return getHibernateTemplate().find(buffer.toString());
    }
    public List getObjectsByCriteria(final DetachedCriteria detachedCriteria)throws Exception{
    	return (List)getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException,SQLException {
				if(detachedCriteria==null) return new ArrayList(); 
				Criteria criteria = detachedCriteria.getExecutableCriteria(session);
				return criteria.list(); 
			}
		});
    }
    public List getObjectsByCriteria(final DetachedCriteria detachedCriteria,final PageInfo pageInfo)throws Exception{
    	return (List)getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException,SQLException {
				if(detachedCriteria==null) return new ArrayList(); 
				Criteria criteria = detachedCriteria.getExecutableCriteria(session); 
				criteria.setFirstResult(pageInfo.getBeginResult());
				criteria.setFetchSize(pageInfo.getPageSize());
				return criteria.list(); 
			}
		});
    }
    /**
     * @see com.dmx.fw.dao.interfaces.Dao#removeObject(java.lang.Class, java.io.Serializable)
     */
    public void removeObject(Class clazz, Serializable id) {
        getHibernateTemplate().delete(getObject(clazz, id));
    }
    public void removeObject(Object o){
    	if(o==null) return;
    	getHibernateTemplate().delete(o);
    }
    
    /**
     * @see com.dmx.fw.dao.interfaces.Dao#find(String hqlString)
     */
    public List find(String queryString){
    	return getHibernateTemplate().find(queryString);
    }
    
    /**
     * @see com.dmx.fw.dao.interfaces.Dao#find(String queryString,Object value)
     */    
    public List find(String queryString,Object value){
    	return getHibernateTemplate().find(queryString, value);
    }
    
    /**
     * @see com.dmx.fw.dao.interfaces.Dao#find(String queryString,Object[] values)
     */
    public List find(String queryString,Object[] values){
    	return getHibernateTemplate().find(queryString,values);
    }
    
    protected static String getIdentifierName(SessionFactory sessionFactory,final Class clazz){
		ClassMetadata catMeta =  sessionFactory.getClassMetadata(clazz);
		return catMeta.getIdentifierPropertyName();
	}

	@Override
	public void saveAll(Collection entities) throws Exception{
		// TODO Auto-generated method stub
		this.getHibernateTemplate().saveOrUpdateAll(entities);
	}
}
